home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Tele / C / Comet2.1.3.cpt / emlib / key.c < prev    next >
Text File  |  1991-08-02  |  39KB  |  2,067 lines

  1. /*
  2.     Copyright Cornell University 1986.  All rights are reserved.
  3. */
  4.  
  5. #include <em.h>
  6.  
  7. #include <h19.h>
  8. #include <macdefs.h>
  9. #include <resdefs.h>
  10. #include <rcodes.h>
  11. #include <3270.h>
  12.  
  13. short keytron;            /* key vector trap has been set up, hazardous to some DA's & succeeding apps */
  14.  
  15. extern char hexchar();
  16. extern short resfid;                /* resource file descriptor */
  17.  
  18. #define BADKEY '\317'
  19. #define MAXKEYCODE 51
  20.  
  21. /* keycode -> control char mapping for option key
  22. ASDFHGZXCV
  23. .BQWERYT.2
  24. ..6....-..
  25. ]OU[IP.LJ.
  26. K.\./NM
  27. */
  28. char optkeymap[MAXKEYCODE] = "\
  29. \001\023\004\006\010\007\032\030\003\026\
  30. \317\002\021\027\005\022\031\024\317\000\
  31. \317\317\036\317\317\317\317\037\317\317\
  32. \035\017\025\033\011\020\317\014\012\317\
  33. \013\317\034\317\177\016\015\317\317\000";
  34.  
  35. /* test a character to see if it should produce a control character */
  36.  
  37. makecontrol(thechar, keycode)
  38. unsigned char * thechar;
  39. unsigned char keycode;
  40. {
  41.     if (keycode < MAXKEYCODE - 1) {
  42.         if (optkeymap[keycode] != BADKEY) {
  43.             /* if good match */
  44.             *thechar = optkeymap[keycode];
  45.             return(TRUE);
  46.         }
  47.     }
  48.     return(FALSE);
  49. }
  50.  
  51.  
  52. /* is the option key down? */
  53.  
  54. optkeydown()
  55. {
  56.     KeyMap thekeys;
  57.  
  58.     GetKeys(&thekeys);
  59.     if (thekeys[1] & (long) 0x0004)
  60.         /* yup, it's down alright */
  61.         return(TRUE);
  62.     else
  63.         return(FALSE);
  64. }
  65.  
  66.  
  67. /* is the control key down? */
  68.  
  69. ctlkeydown()
  70. {
  71.     KeyMap thekeys;
  72.  
  73.     GetKeys(&thekeys);
  74.     if (thekeys[1] & (long) 0x8000)
  75.         /* yup, it's down alright */
  76.         return(TRUE);
  77.     else
  78.         return(FALSE);
  79. }
  80.  
  81.  
  82. /* place the action codes associated with a key on the action queue;
  83.     distinguishes between ibm or ascii mode, old and new keyboards, 
  84.     function or character mapping for keypad */
  85.  
  86. keymap(keycode, thechar, modifiers)
  87. unsigned char keycode;
  88. unsigned char thechar;
  89. unsigned short modifiers;
  90. {
  91.     short count;
  92.     unsigned long keyid;
  93.     struct token * actptr;
  94.     extern SysEnvRec environs;
  95.  
  96.     if (keydp->keyaltset) 
  97.         /* turn off the mouse state: button down in key dialog interpreted as ALT */
  98.         modifiers &= ~btnState;
  99.     else
  100.         modifiers |= btnState;
  101.     
  102.     /* switch the -/+ key for the Standard keypad if user has configured it... */
  103.     if (keypadswitch && environs.keyBoardType == envStandADBKbd) {
  104.         if (keycode == 0x4e) {
  105.             /* - key, make it a + key */
  106.             keycode = 0x45;
  107.             thechar = '+';
  108.         }
  109.         else if (keycode == 0x45) {
  110.             /* + key, make it a - key */
  111.             keycode = 0x4e;
  112.             thechar = '-';
  113.         }
  114.     }
  115.  
  116.     /* TODO the following derivation of keyid should be unnecessary */
  117.     keyid = modifiers;
  118.     keyid <<= 16;
  119.     keyid |= (keycode << 8) & 0xFFFF;
  120.     keyid |= thechar & 0x00FF;
  121.  
  122.     if (keydp->dokeymacros && (actptr = keyxfind(keyid, &count)) != NULL) {
  123.         /* there is a key macro for this key, put actions on the action queue */
  124.         for ( ;  count--; actptr++) {
  125.             keyputaction(actptr->class, actptr->entry);
  126.         }
  127.         return(0);
  128.     }
  129.     if (modifiers & cmdKey 
  130.             && !(modifiers & optionKey) 
  131.             && !(modifiers & shiftKey)
  132.             && !(modifiers & ctrlKey)
  133.         ) 
  134.     {
  135.         /* of the modifier keys, only the command key/caps lock are down */
  136.         if (thechar == '.') {
  137.             /* user wants to abort actions */
  138.             flushactions(keydp);
  139.             return(0);
  140.         }
  141.         else if (keycode < 52) {
  142.             /* and the keycode is less than the keypad codes */
  143.             long comm;
  144.     
  145.             /* is this a menu key ? */
  146.             if (comm = MenuKey(thechar)) {
  147.                 docommand(comm);
  148.                 return(0);
  149.             }
  150.         }
  151.     }
  152.     if (keydp->ibm_keymode) {
  153.         if (keyboard == OLDKEYBOARD) {
  154.             switch (keydp->keypad) {
  155.                 /* function key keypad in use */
  156.                 case NORMKEYPAD: {
  157.                     if (ibmokpnorm(keycode))
  158.                         return(0);
  159.                     break;
  160.                 }
  161.                 case KEYPAD1:
  162.                 case KEYPAD2: {
  163.                     if (ibmokp2(thechar, keycode, modifiers))
  164.                         return(0);
  165.                     break;
  166.                 }
  167.                 case KEYPAD3: {
  168.                     if (ibmokp3(keycode))
  169.                         return(0);
  170.                     break;
  171.                 }
  172.             }
  173.         }
  174.         else {
  175.             /* uses Mac Plus or higher keyboard, which has different keypad positions! */
  176.             if (fkeytest(keycode))
  177.                 /* Saratoga function key was depressed */
  178.                 return(0);
  179.             switch (keydp->keypad) {
  180.                 /* function key keypad in use */
  181.                 case NORMKEYPAD: {
  182.                     if (ibmnkpnorm(thechar, keycode))
  183.                         return(0);
  184.                     break;
  185.                 }
  186.                 case KEYPAD1:
  187.                 case KEYPAD2: {
  188.                     if (ibmnkp2(thechar, keycode, modifiers))
  189.                         return(0);
  190.                     break;
  191.                 }
  192.                 case KEYPAD3: {
  193.                     if (ibmnkp3(thechar, keycode))
  194.                         return(0);
  195.                     break;
  196.                 }
  197.             }
  198.         }
  199.         if (modifiers & optionKey) {
  200.             if (ibmtestpf(keycode, modifiers))
  201.                 /* it was a pf key on main keyboard */
  202.                 return(0);
  203.         }
  204.         switch (thechar) {
  205.             /* handle the rest of the ibm_keymode keys */
  206.             /* TODO fix BS so it is more intelligent */
  207.             case BS: {
  208.                 if (modifiers & cmdKey) {
  209.                     keyputaction(RSLT_LCAC, DEL_CHAR);
  210.                 }
  211.                 else if (modifiers & optionKey) {
  212.                     keyputaction(RSLT_LCAC, BACKSP_DEL);
  213.                 }
  214.                 else if (modifiers & shiftKey) {
  215.                     keyputaction(RSLT_LCAC, BACKSP_BLANK);
  216.                 }
  217.                 else if (keydp->event_reg & INSERT) {
  218.                     keyputaction(RSLT_LCAC, BACKSP_DEL);
  219.                 }
  220.                 else {
  221.                     keyputaction(RSLT_LCAC, BACKSP_BLANK);
  222.                 }
  223.                 break;
  224.             }
  225.             case TAB: {
  226.                 if (modifiers & shiftKey  || modifiers & cmdKey) {
  227.                     keyputaction(RSLT_MVCR, BACK_TAB);
  228.                 }
  229.                 else
  230.                     /* regular tab */
  231.                     keyputaction(RSLT_MVCR, TAB_FWD);
  232.                 break;
  233.             }
  234.             case ETX: {
  235.                 /* Enter key */
  236.                 if (modifiers & shiftKey) {
  237.                     keyputaction(RSLT_PFKY, PA1);
  238.                 }
  239.                 else if (modifiers & cmdKey) {
  240.                     keyputaction(RSLT_PFKY, PA3);
  241.                 }
  242.                 else if (modifiers & optionKey) {
  243.                     keyputaction(RSLT_PFKY, CLEAR);
  244.                 }
  245.                 else {
  246.                     keyputaction(RSLT_PFKY, PA2);
  247.                 }
  248.                 break;
  249.             }
  250.             case CR: {
  251.                 /* make a newline if shifted */
  252.                 if (modifiers & shiftKey || keydp->crtonl
  253.                         && !(modifiers & shiftKey && keydp->crtonl) ) {
  254.                     /* reverses action when keydp->crtonl true */
  255.                     keyputaction(RSLT_MVCR, NEW_LINE);
  256.                 }
  257.                 else {
  258.                     keyputaction(RSLT_PFKY, ENTER);
  259.                 }
  260.                 break;
  261.             }
  262.             default: {
  263.                 /* put out plain character */
  264.                 if (modifiers & cmdKey)
  265.                     /* any cmd combos should have been handled already */
  266.                     break;
  267.                 keyputaction(RSLT_ASCI, thechar);
  268.             }
  269.         }
  270.     }
  271.     else {
  272.         /* ASCII keyboard */
  273.         if ((modifiers & optionKey) || (modifiers & ctrlKey)) {
  274.             /* should we interpret this as a control key? */
  275.             char newchar;
  276.             
  277.             switch (thechar) {
  278.                 case CR: {
  279.                     if (!keydp->crtonl)
  280.                         thechar = LF;
  281.                     keyputaction(RSLT_ASCI, thechar);
  282.                     return(0);
  283.                 }
  284.                 case '`': {
  285.                     if (!keydp->escmap) {
  286.                         /* make a '`' rather than an ESC when option down */
  287.                         thechar = ESC;
  288.                     }
  289.                     keyputaction(RSLT_ASCI, thechar);
  290.                     return(0);
  291.                 }
  292.                 case BS: {
  293.                     if (keydp->ba_bs) {
  294.                         /* convert to delete */
  295.                         thechar = DEL;
  296.                     }
  297.                     keyputaction(RSLT_ASCI, thechar);
  298.                     return(0);
  299.                 }
  300.             }
  301.             newchar = thechar;
  302.             if (!(modifiers & shiftKey) && !(modifiers & cmdKey)
  303.                 && ((modifiers & optionKey && !(modifiers & ctrlKey))
  304.                     || (modifiers & ctrlKey && !(modifiers & optionKey)))
  305.                 ) 
  306.             {
  307.                 /* the Control or Option key is down all by itself */
  308.                 if (makecontrol(&newchar, keycode)) {
  309.                     /* interpret as a control key */
  310.                     keyputaction(RSLT_ASCI, newchar);
  311.                     return(0);
  312.                 }
  313.             }
  314.             return(-1);
  315.         }
  316.         /* handle things which are spotted by the keycode */
  317.         if (keydp->termtype == TERM_VT100
  318.                 || keydp->termtype == TERM_VT102
  319.                 || keydp->termtype == TERM_VT220
  320.             ) {
  321.             /* we're doing vt100 emulation or vt52 for vt100 */
  322.             if ((keydp->mode == VT100MODE && keydp->vtaltkeypad)
  323.                 || (keydp->mode != VT100MODE && keydp->vt52altkeypad)) {
  324.                 /* keypad sends application codes */
  325.                 if (vtkeychk(&thechar, keycode)) {
  326.                     return(0);
  327.                 }
  328.             }
  329.             else {
  330.                 if (dovtkeypad(&thechar, keycode)) {
  331.                     /* character handled by routine */
  332.                     return(0);
  333.                 }
  334.             }
  335.             if (vt200keychk(&thechar, keycode)) {
  336.                 return(0);
  337.             }
  338.         }
  339.         else {
  340.             if (stdkeypad(&thechar, keycode))
  341.                 /* character handled by routine */
  342.                 return(0);
  343.         }
  344.         /* ascii mode responses */
  345.         switch (thechar) {
  346.             case '`': {
  347.                 if (keydp->escmap)
  348.                     /* make an escape */
  349.                     thechar = ESC;
  350.                 break;
  351.             }
  352.             case BS: {
  353.                 if (!keydp->ba_bs) {
  354.                     thechar = DEL;
  355.                 }
  356.                 break;
  357.             }
  358.             case CR: {
  359.                 /* make a newline if shifted or keydp->crtonl set */
  360.                 if (keydp->mode == VT100MODE) {
  361.                     if (keydp->vtnewline) {
  362.                         /* send CR-LF for CR */
  363.                         keyputaction(RSLT_ASCI, thechar);
  364.                         if (! (modifiers & shiftKey)) {
  365.                             thechar = LF;
  366.                         }
  367.                     }
  368.                 }
  369.                 else if (modifiers & shiftKey || keydp->crtonl) {
  370.                     thechar = LF;
  371.                 }
  372.                 break;
  373.             }
  374.         }
  375.         keyputaction(RSLT_ASCI, thechar);
  376.     }
  377. }
  378.  
  379.  
  380. /* returns TRUE if routine handles key */
  381.  
  382. dovtkeypad(charp, keycode)
  383. unsigned char *charp;
  384. unsigned char keycode;
  385. {
  386.     if (keyboard == OLDKEYBOARD) {
  387.         switch (keycode) {
  388.             /* keys from left to right, top to bottom */
  389.             /* top 4 keys are PF1 - PF4 */
  390.             case 0x47: {
  391.                 /* Clear == pf1 */
  392.                 sendvtkeyfunc('P');
  393.                 break;
  394.             }
  395.             case 0x4e: {
  396.                 /* - == pf2 */
  397.                 sendvtkeyfunc('Q');
  398.                 break;
  399.             }
  400.             case 0x46: {
  401.                 /* '+' key == pf3 */
  402.                 sendvtkeyfunc('R');
  403.                 break;
  404.             }
  405.             case 0x42: {
  406.                 /* * == pf4 */
  407.                 sendvtkeyfunc('S');
  408.                 break;
  409.             }
  410.             case 0x4d: {
  411.                 /* /  == - on vt100) */
  412.                 keyputaction(RSLT_ASCI, '-');
  413.                 break;
  414.             }
  415.             case 0x48: {
  416.                 /* ',' == ',' on vt100 */
  417.                 keyputaction(RSLT_ASCI, ',');
  418.                 break;
  419.             }
  420.             case 0x4c: {
  421.                 /* make ENTER == CR */
  422.                 *charp = CR;
  423.                 return(FALSE);
  424.                 break;
  425.             }
  426.             default: {
  427.                 return(FALSE);
  428.             }
  429.         }
  430.     }
  431.     else {
  432.         /* uses Mac Plus keyboard, which has different keypad positions! */
  433.         switch (keycode) {
  434.             /* keys from left to right, top to bottom */
  435.             case 0x47: {
  436.                 /* Clear == pf1 */
  437.                 sendvtkeyfunc('P');
  438.                 break;
  439.             }
  440.             case 0x51:
  441.             case 0x48: {
  442.                 /* '=' == pf2 */
  443.                 if (*charp == CTLUNDERSCORE)
  444.                     /* down arrow key on mac+ */
  445.                     keyputaction(RSLT_MVCR, DOWN_ARROW);
  446.                 else
  447.                     sendvtkeyfunc('Q');
  448.                 break;
  449.             }
  450.             case 0x4b:
  451.             case 0x4d: {
  452.                 /* / == pf3 */
  453.                 if (*charp == CTLHAT)
  454.                     /* up arrow key on mac+ */
  455.                     keyputaction(RSLT_MVCR, UP_ARROW);
  456.                 else
  457.                     sendvtkeyfunc('R');
  458.                 break;
  459.             }
  460.             case 0x43:        /* + key abd */
  461.             case 0x42:      /* + key mac+ */
  462.             {
  463.                 /* * == pf4 */
  464.                 if (*charp == CTLRBRACK)
  465.                     /* right arrow key on mac+ */
  466.                     keyputaction(RSLT_MVCR, RIGHT_ARROW);
  467.                 else
  468.                     sendvtkeyfunc('S');
  469.                 break;
  470.             }
  471.             case 0x45:    /* + key abd */
  472.             case 0x46:     /* + key mac+ */
  473.             {
  474.                 /* '+' key == , */
  475.                 if (*charp == CTLBACKSLASH)
  476.                     /* left arrow key on mac+ */
  477.                     keyputaction(RSLT_MVCR, LEFT_ARROW);
  478.                 else
  479.                     keyputaction(RSLT_ASCI, ',');
  480.                 break;
  481.             }
  482.             case 0x4e: {
  483.                 /* '-' == '-' */
  484.                 keyputaction(RSLT_ASCI, '-');
  485.                 break;
  486.             }
  487.             case 0x4c: {
  488.                 /* make ENTER == Enter */
  489.                 *charp = CR;
  490.                 return(FALSE);
  491.                 break;
  492.             }
  493.             case 0x7b: {
  494.                 /* left arrow key saratoga */
  495.                 keyputaction(RSLT_MVCR, LEFT_ARROW);
  496.                 break;
  497.             }
  498.             case 0x7c: {
  499.                 /* right arrow key saratoga */
  500.                 keyputaction(RSLT_MVCR, RIGHT_ARROW);
  501.                 break;
  502.             }
  503.             case 0x7d: {
  504.                 /* down arrow key saratoga */
  505.                 keyputaction(RSLT_MVCR, DOWN_ARROW);
  506.                 break;
  507.             }
  508.             case 0x7e: {
  509.                 /* up arrow key saratoga */
  510.                 keyputaction(RSLT_MVCR, UP_ARROW);
  511.                 break;
  512.             }
  513.             default: {
  514.                 return(FALSE);
  515.             }
  516.         }
  517.     }
  518.     return(TRUE);
  519. }
  520.  
  521.  
  522. vtkeychk(charp, keycode)
  523. unsigned char *charp;
  524. unsigned char keycode;
  525. {
  526.     if (keyboard == OLDKEYBOARD) {
  527.         switch (keycode) {
  528.             /* keys from left to right, top to bottom */
  529.             case 0x47: {
  530.                 /* Clear == pf1 */
  531.                 sendvtkeyfunc('P');
  532.                 break;
  533.             }
  534.             case 0x4e: {
  535.                 /* - == pf2 */
  536.                 sendvtkeyfunc('Q');
  537.                 break;
  538.             }
  539.             case 0x46: {
  540.                 /* '+' key == pf3 */
  541.                 sendvtkeyfunc('R');
  542.                 break;
  543.             }
  544.             case 0x42: {
  545.                 /* * == pf4 */
  546.                 sendvtkeyfunc('S');
  547.                 break;
  548.             }
  549.             case 0x59: {
  550.                 /* 7 */
  551.                 sendvtkeyfunc('w');
  552.                 break;
  553.             }
  554.             case 0x5b: {
  555.                 /* 8 */
  556.                 sendvtkeyfunc('x');
  557.                 break;
  558.             }
  559.             case 0x5c: {
  560.                 /* 9 */
  561.                 sendvtkeyfunc('y');
  562.                 break;
  563.             }
  564.             case 0x4d: {
  565.                 /* /  (- on vt100) */
  566.                 sendvtkeyfunc('m');
  567.                 break;
  568.             }
  569.             case 0x56: {
  570.                 /* 4 */
  571.                 sendvtkeyfunc('t');
  572.                 break;
  573.             }
  574.             case 0x57: {
  575.                 /* 5 */
  576.                 sendvtkeyfunc('u');
  577.                 break;
  578.             }
  579.             case 0x58: {
  580.                 /* 6 */
  581.                 sendvtkeyfunc('v');
  582.                 break;
  583.             }
  584.             case 0x48: {
  585.                 /* ',' */
  586.                 sendvtkeyfunc('l');
  587.                 break;
  588.             }
  589.             case 0x53: {
  590.                 /* '1' */
  591.                 sendvtkeyfunc('q');
  592.                 break;
  593.             }
  594.             case 0x54: {
  595.                 /* '2' */
  596.                 sendvtkeyfunc('r');
  597.                 break;
  598.             }
  599.             case 0x55: {
  600.                 /* '3' */
  601.                 sendvtkeyfunc('s');
  602.                 break;
  603.             }
  604.             case 0x4c: {
  605.                 /* ENTER */
  606.                 sendvtkeyfunc('M');
  607.                 break;
  608.             }
  609.             case 0x52: {
  610.                 /* '0' */
  611.                 sendvtkeyfunc('p');
  612.                 break;
  613.             }
  614.             case 0x41: {
  615.                 /* '.' */
  616.                 sendvtkeyfunc('n');
  617.                 break;
  618.             }
  619.             default: {
  620.                 return(FALSE);
  621.             }
  622.         }
  623.     }
  624.     else {
  625.         /* uses Mac Plus keyboard, which has different keypad positions! */
  626.         switch (keycode) {
  627.             /* keys from left to right, top to bottom */
  628.             case 0x47: {
  629.                 /* Clear == pf1 */
  630.                 sendvtkeyfunc('P');
  631.                 break;
  632.             }
  633.             case 0x51:
  634.             case 0x48: {
  635.                 /* '=' == pf2 */
  636.                 if (*charp == CTLUNDERSCORE)
  637.                     /* down arrow key on mac+ */
  638.                     keyputaction(RSLT_MVCR, DOWN_ARROW);
  639.                 else
  640.                     sendvtkeyfunc('Q');
  641.                 break;
  642.             }
  643.             case 0x4b:
  644.             case 0x4d: {
  645.                 /* / == pf3 */
  646.                 if (*charp == CTLHAT)
  647.                     /* up arrow key on mac+ */
  648.                     keyputaction(RSLT_MVCR, UP_ARROW);
  649.                 else
  650.                     sendvtkeyfunc('R');
  651.                 break;
  652.             }
  653.             case 0x43:        /* + key abd */
  654.             case 0x42:      /* + key mac+ */
  655.             {
  656.                 /* * == pf4 */
  657.                 if (*charp == CTLRBRACK)
  658.                     /* right arrow key on mac+ */
  659.                     keyputaction(RSLT_MVCR, RIGHT_ARROW);
  660.                 else
  661.                     sendvtkeyfunc('S');
  662.                 break;
  663.             }
  664.             case 0x59: {
  665.                 /* 7 */
  666.                 sendvtkeyfunc('w');
  667.                 break;
  668.             }
  669.             case 0x5b: {
  670.                 /* 8 */
  671.                 sendvtkeyfunc('x');
  672.                 break;
  673.             }
  674.             case 0x5c: {
  675.                 /* 9 */
  676.                 sendvtkeyfunc('y');
  677.                 break;
  678.             }
  679.             case 0x45:    /* + key abd */
  680.             case 0x46:     /* + key mac+ */
  681.             {
  682.                 /* '+'  */
  683.                 if (*charp == CTLBACKSLASH)
  684.                     /* left arrow key on mac+ */
  685.                     keyputaction(RSLT_MVCR, LEFT_ARROW);
  686.                 else
  687.                     sendvtkeyfunc('l');
  688.                 break;
  689.             }
  690.             case 0x56: {
  691.                 /* 4 */
  692.                 sendvtkeyfunc('t');
  693.                 break;
  694.             }
  695.             case 0x57: {
  696.                 /* 5 */
  697.                 sendvtkeyfunc('u');
  698.                 break;
  699.             }
  700.             case 0x58: {
  701.                 /* 6 */
  702.                 sendvtkeyfunc('v');
  703.                 break;
  704.             }
  705.             case 0x4e: {
  706.                 /* '-' */
  707.                 sendvtkeyfunc('m');
  708.                 break;
  709.             }
  710.             case 0x53: {
  711.                 /* '1' */
  712.                 sendvtkeyfunc('q');
  713.                 break;
  714.             }
  715.             case 0x54: {
  716.                 /* '2' */
  717.                 sendvtkeyfunc('r');
  718.                 break;
  719.             }
  720.             case 0x55: {
  721.                 /* '3' */
  722.                 sendvtkeyfunc('s');
  723.                 break;
  724.             }
  725.             case 0x4c: {
  726.                 /* ENTER */
  727.                 sendvtkeyfunc('M');
  728.                 break;
  729.             }
  730.             case 0x52: {
  731.                 /* '0'  */
  732.                 sendvtkeyfunc('p');
  733.                 break;
  734.             }
  735.             case 0x41: {
  736.                 /* '.' */
  737.                 sendvtkeyfunc('n');
  738.                 break;
  739.             }
  740.             case 0x7b: {
  741.                 /* left arrow key saratoga */
  742.                 keyputaction(RSLT_MVCR, LEFT_ARROW);
  743.                 break;
  744.             }
  745.             case 0x7c: {
  746.                 /* right arrow key saratoga */
  747.                 keyputaction(RSLT_MVCR, RIGHT_ARROW);
  748.                 break;
  749.             }
  750.             case 0x7d: {
  751.                 /* down arrow key saratoga */
  752.                 keyputaction(RSLT_MVCR, DOWN_ARROW);
  753.                 break;
  754.             }
  755.             case 0x7e: {
  756.                 /* up arrow key saratoga */
  757.                 keyputaction(RSLT_MVCR, UP_ARROW);
  758.                 break;
  759.             }
  760.             default: {
  761.                 return(FALSE);
  762.             }
  763.         }
  764.     }
  765.     return(TRUE);
  766. }
  767.  
  768.  
  769. /* Apple Extended (saratoga) keyboard has keys to support vt200 apps... */
  770.  
  771. vt200keychk(charp, keycode)
  772. unsigned char *charp;
  773. unsigned char keycode;
  774. {
  775.     char thecode;
  776.     
  777.     switch (keycode) {
  778.         case 0x72: {
  779.             /* FIND -- help saratoga */
  780.             thecode = '1';
  781.             break;
  782.         }
  783.         case 0x73: {
  784.             /* Insert Here -- home saratoga */
  785.             thecode = '2';
  786.             break;
  787.         }
  788.         case 0x74: {
  789.             /* Remove -- page up saratoga */
  790.             thecode = '3';
  791.             break;
  792.         }
  793.         case 0x75: {
  794.             /* Select -- DEL RIGHT X-> saratoga */
  795.             thecode = '4';
  796.             break;
  797.         }
  798.         case 0x77: {
  799.             /* Prev Screen -- end saratoga */
  800.             thecode = '5';
  801.             break;
  802.         }
  803.         case 0x79: {
  804.             /* Next Screen -- page down saratoga */
  805.             thecode = '6';
  806.             break;
  807.         }
  808.         default: {
  809.             return(FALSE);
  810.         }
  811.     }
  812.     /* send the code imbedded in the proper escape sequence */
  813.     sendvt102key(thecode);
  814.     return(TRUE);
  815. }
  816.  
  817. /* interpret keycode into action, routine returns TRUE if it handles */
  818.  
  819. stdkeypad(charp, keycode)
  820. unsigned char *charp;
  821. unsigned char keycode;
  822. {
  823.     if (keyboard == OLDKEYBOARD) {
  824.         switch (keycode) {
  825.             case 71: {
  826.                 /* Clear == ESCAPE */
  827.                 keyputaction(RSLT_ASCI, ESC);
  828.                 break;
  829.             }
  830.             case 70: {
  831.                 /* '+' key == + */
  832.                 keyputaction(RSLT_ASCI, '+');
  833.                 break;
  834.             }
  835.             case 76: {
  836.                 /* ENTER == Carriage Return */
  837.                 keyputaction(RSLT_ASCI, CR);
  838.                 break;
  839.             }
  840.             case 66: {
  841.                 /* * == * */
  842.                 keyputaction(RSLT_ASCI, '*');
  843.                 break;
  844.             }
  845.             case 77: {
  846.                 /* / == / */
  847.                 keyputaction(RSLT_ASCI, '/');
  848.                 break;
  849.             }
  850.             case 72: {
  851.                 /* ',' == ',' */
  852.                 keyputaction(RSLT_ASCI, ',');
  853.                 break;
  854.             }
  855.             default: {
  856.                 return(FALSE);
  857.             }
  858.         }
  859.     }
  860.     else {
  861.         /* uses Mac Plus keyboard, which has different keypad positions! */
  862.         switch (keycode) {
  863.             case 71: {
  864.                 /* Clear == ESC */
  865.                 keyputaction(RSLT_ASCI, ESC);
  866.                 break;
  867.             }
  868.             case 123:
  869.             case 69:
  870.             case 70: {
  871.                 /* '+' key == + */
  872.                 if (*charp == CTLBACKSLASH)
  873.                     /* left arrow key on mac+ */
  874.                     keyputaction(RSLT_MVCR, LEFT_ARROW);
  875.                 else
  876.                     keyputaction(RSLT_ASCI, '+');
  877.                 break;
  878.             }
  879.             case 76: {
  880.                 /* ENTER == CR */
  881.                 keyputaction(RSLT_ASCI, CR);
  882.                 break;
  883.             }
  884.             case 124:
  885.             case 67:
  886.             case 66: {
  887.                 /* * == * */
  888.                 if (*charp == CTLRBRACK)
  889.                     /* right arrow key on mac+ */
  890.                     keyputaction(RSLT_MVCR, RIGHT_ARROW);
  891.                 else
  892.                     keyputaction(RSLT_ASCI, '*');
  893.                 break;
  894.             }
  895.             case 126:
  896.             case 75:
  897.             case 77: {
  898.                 /* / == / */
  899.                 if (*charp == CTLHAT)
  900.                     /* up arrow key on mac+ */
  901.                     keyputaction(RSLT_MVCR, UP_ARROW);
  902.                 else
  903.                     keyputaction(RSLT_ASCI, '/');
  904.                 break;
  905.             }
  906.             case 125:
  907.             case 81:
  908.             case 72: {
  909.                 /* '=' == '=' */
  910.                 if (*charp == CTLUNDERSCORE)
  911.                     /* down arrow key on mac+ */
  912.                     keyputaction(RSLT_MVCR, DOWN_ARROW);
  913.                 else
  914.                     keyputaction(RSLT_ASCI, '=');
  915.                 break;
  916.             }
  917.             default: {
  918.                 return(FALSE);
  919.             }
  920.         }
  921.     }
  922.     return(TRUE);
  923. }
  924.  
  925.  
  926. /* embed the code in the appropriate escape sequence, depending on the mode */
  927.  
  928. sendvtkeyfunc(thechar)
  929. unsigned char thechar;
  930. {
  931.     keyputaction(RSLT_ASCI, ESC);
  932.     if (keydp->mode == VT100MODE) 
  933.         keyputaction(RSLT_ASCI, 'O');
  934.     else if (thechar != 'P'
  935.             && thechar != 'Q'
  936.             && thechar != 'R'
  937.             && thechar != 'S')
  938.         /* vt52 function keys have no prefix, unlike other app mode keypad keys */
  939.         keyputaction(RSLT_ASCI, '?');
  940.     keyputaction(RSLT_ASCI, thechar);
  941. }
  942.  
  943. /* imbed the code in the escape sequence for the 6 extra keys */
  944.  
  945. sendvt102key(thechar)
  946. unsigned char thechar;
  947. {
  948.     keyputaction(RSLT_ASCI, ESC);
  949.     keyputaction(RSLT_ASCI, '[');
  950.     keyputaction(RSLT_ASCI, thechar);
  951.     keyputaction(RSLT_ASCI, '~');
  952. }
  953.  
  954. ibmokpnorm(keycode)
  955. unsigned char keycode;
  956. {
  957.     /* original keypad NORMKEYPAD */
  958.     switch (keycode) {
  959.         case 71: {
  960.             /* Clear == Clear */
  961.             keyputaction(RSLT_PFKY, CLEAR);
  962.             break;
  963.         }
  964.         case 70: {
  965.             /* '+' key == + */
  966.             keyputaction(RSLT_ASCI, '+');
  967.             break;
  968.         }
  969.         case 76: {
  970.             /* make ENTER == Enter */
  971.             keyputaction(RSLT_PFKY, ENTER);
  972.             break;
  973.         }
  974.         case 66: {
  975.             /* '*' == * */
  976.             keyputaction(RSLT_ASCI, '*');
  977.             break;
  978.         }
  979.         case 77: {
  980.             /* '/' == / */
  981.             keyputaction(RSLT_ASCI, '/');
  982.             break;
  983.         }
  984.         case 72: {
  985.             /* ',' == ',' */
  986.             keyputaction(RSLT_ASCI, ',');
  987.             break;
  988.         }
  989.         default: {
  990.             return(FALSE);
  991.         }
  992.     }
  993.     return(TRUE);
  994. }
  995.  
  996.  
  997. /* for historical reasons this code handles both keypads 1 & 2 */
  998.  
  999. ibmokp2(thechar, keycode, modifiers)
  1000. unsigned char thechar;
  1001. unsigned char keycode;
  1002. unsigned short modifiers;
  1003. {
  1004.     unsigned char theact = 0;
  1005.     
  1006.     switch (keycode) {
  1007.         /* handle the keys on the keypad, which produce PF, PA, INS, CLR, & ENTER */
  1008.         case 82: {
  1009.             /* '0', next keypad PF key is PF13-24 or PA2 & cousins */
  1010.             if (keydp->keypad == KEYPAD2) {
  1011.                 if (modifiers & shiftKey) 
  1012.                     keyputaction(RSLT_PFKY, PA1);
  1013.                 else if (modifiers & cmdKey) 
  1014.                     keyputaction(RSLT_PFKY, PA3);
  1015.                 else if (modifiers & optionKey) 
  1016.                     keyputaction(RSLT_PFKY, CLEAR);
  1017.                 else
  1018.                     keyputaction(RSLT_PFKY, PA2);
  1019.             }
  1020.             else
  1021.                 keyputaction(RSLT_PFKY, PFSHIFT);
  1022.             break;
  1023.         }
  1024.         case 66: {
  1025.             /* * == PA1 or SHIFT */
  1026.             if (keydp->keypad == KEYPAD2)
  1027.                 keyputaction(RSLT_PFKY, PFSHIFT);
  1028.             else
  1029.                 keyputaction(RSLT_PFKY, PA1);
  1030.             break;
  1031.         }
  1032.         case 77: {
  1033.             /* - == PA2 or PA1 */
  1034.             if (keydp->keypad == KEYPAD2)
  1035.                 keyputaction(RSLT_PFKY, PA1);
  1036.             else {
  1037.                 if (modifiers & cmdKey)
  1038.                     keyputaction(RSLT_PFKY, PA3);
  1039.                 else
  1040.                     keyputaction(RSLT_PFKY, PA2);
  1041.             }
  1042.             break;
  1043.         }
  1044.         case 72: {
  1045.             /* , == Clear */
  1046.             keyputaction(RSLT_PFKY, CLEAR);
  1047.             break;
  1048.         }
  1049.         case 76: {
  1050.             /* ENTER == Enter */
  1051.             keyputaction(RSLT_PFKY, ENTER);
  1052.             break;
  1053.         }
  1054.         case 65: {
  1055.             /* . == Insert */
  1056.             keyputaction(RSLT_LCAC, INSRT);
  1057.             break;
  1058.         }
  1059.         /* following this point are the 12 PF keys */
  1060.         case 71: {
  1061.             /* 'Clear' == PF1 */
  1062.             keyputaction(RSLT_PFKY, PF1);
  1063.             break;
  1064.         }
  1065.         case 78: {
  1066.             /* '-' key == PF2 */
  1067.             keyputaction(RSLT_PFKY, PF2);
  1068.             break;
  1069.         }
  1070.         case 70: {
  1071.             /* '+' key == PF3 */
  1072.             keyputaction(RSLT_PFKY, PF3);
  1073.             break;
  1074.         }
  1075.         case 89: {
  1076.             /* 7 = PF4 */
  1077.             keyputaction(RSLT_PFKY, PF4);
  1078.             break;
  1079.         }
  1080.         case 91: {
  1081.             /* 8 = PF5 */
  1082.             keyputaction(RSLT_PFKY, PF5);
  1083.             break;
  1084.         }
  1085.         case 92:  {
  1086.             /* 9 = PF6 */
  1087.             keyputaction(RSLT_PFKY, PF6);
  1088.             break;
  1089.         }
  1090.         case 86: {
  1091.             /* 4 = PF7 */
  1092.             keyputaction(RSLT_PFKY, PF7);
  1093.             break;
  1094.         }
  1095.         case 87: {
  1096.             /* 5 = PF8 */
  1097.             keyputaction(RSLT_PFKY, PF8);
  1098.             break;
  1099.         }
  1100.         case 88: {
  1101.             /* 6 = PF9 */
  1102.             keyputaction(RSLT_PFKY, PF9);
  1103.             break;
  1104.         }
  1105.         case 83: {
  1106.             /* 1 = PF10 */
  1107.             keyputaction(RSLT_PFKY, PF10);
  1108.             break;
  1109.         }
  1110.         case 84: {
  1111.             /* 2 = PF11 */
  1112.             keyputaction(RSLT_PFKY, PF11);
  1113.             break;
  1114.         }
  1115.         case 85: {
  1116.             /* 3 = PF12 */
  1117.             keyputaction(RSLT_PFKY, PF12);
  1118.             break;
  1119.         }
  1120.         default:
  1121.             /* no keypad keys depressed, fall through */
  1122.             return(FALSE);
  1123.     }
  1124.     return(TRUE);
  1125. }
  1126.  
  1127.  
  1128. ibmokp3(keycode)
  1129. unsigned char keycode;
  1130. {
  1131.     unsigned char theact = 0;
  1132.     
  1133.     /* do the new Lynn keypad like PAD1 but inverted */
  1134.     switch (keycode) {
  1135.     /* handle the keys on the keypad, which produce PF, PA, INS, CLR, & ENTER */
  1136.         case 82: {
  1137.             /* 0 == SHIFT */
  1138.             keyputaction(RSLT_PFKY, PFSHIFT);
  1139.             break;
  1140.         }
  1141.         case 66: {
  1142.             /* '*', next keypad PF key is PA1 */
  1143.             keyputaction(RSLT_PFKY, PA1);
  1144.             break;
  1145.         }
  1146.         case 77: {
  1147.             /* - == PA2 or PA1 */
  1148.             keyputaction(RSLT_PFKY, PA2);
  1149.             break;
  1150.         }
  1151.         case 72: {
  1152.             /* , or + == Clear */
  1153.             keyputaction(RSLT_PFKY, CLEAR);
  1154.             break;
  1155.         }
  1156.         case 76: {
  1157.             /* ENTER == Enter */
  1158.             keyputaction(RSLT_PFKY, ENTER);
  1159.             break;
  1160.         }
  1161.         case 65: {
  1162.             /* . == Insert */
  1163.             keyputaction(RSLT_LCAC, INSRT);
  1164.             break;
  1165.         }
  1166.         /* following this point are the 12 PF keys */
  1167.         case 83: {
  1168.             /* 1 = PF1 */
  1169.             keyputaction(RSLT_PFKY, PF1);
  1170.             break;
  1171.         }
  1172.         case 84: {
  1173.             /* 2 = PF2 */
  1174.             keyputaction(RSLT_PFKY, PF2);
  1175.             break;
  1176.         }
  1177.         case 85: {
  1178.             /* 3 = PF3 */
  1179.             keyputaction(RSLT_PFKY, PF3);
  1180.             break;
  1181.         }
  1182.         case 86: {
  1183.             /* 4 = PF4 */
  1184.             keyputaction(RSLT_PFKY, PF4);
  1185.             break;
  1186.         }
  1187.         case 87: {
  1188.             /* 5 = PF5 */
  1189.             keyputaction(RSLT_PFKY, PF5);
  1190.             break;
  1191.         }
  1192.         case 88: {
  1193.             /* 6 = PF6 */
  1194.             keyputaction(RSLT_PFKY, PF6);
  1195.             break;
  1196.         }
  1197.         case 89: {
  1198.             /* 7 = PF7 */
  1199.             keyputaction(RSLT_PFKY, PF7);
  1200.             break;
  1201.         }
  1202.         case 91: {
  1203.             /* 8 = PF8 */
  1204.             keyputaction(RSLT_PFKY, PF8);
  1205.             break;
  1206.         }
  1207.         case 92:  {
  1208.             /* 9 = PF9 */
  1209.             keyputaction(RSLT_PFKY, PF9);
  1210.             break;
  1211.         }
  1212.         case 71: {
  1213.             /* 'Clear' == PF10 */
  1214.             keyputaction(RSLT_PFKY, PF10);
  1215.             break;
  1216.         }
  1217.         case 78: {
  1218.             /* '-' key == PF11 */
  1219.             keyputaction(RSLT_PFKY, PF11);
  1220.             break;
  1221.         }
  1222.         case 70: {
  1223.             /* '+' key == PF12 */
  1224.             keyputaction(RSLT_PFKY, PF12);
  1225.             break;
  1226.         }
  1227.         default:
  1228.             /* no keypad keys depressed, fall through */
  1229.             return(FALSE);
  1230.     }
  1231.     return(TRUE);
  1232. }
  1233.  
  1234.  
  1235. /* test to see if an F1-F15 key has been depressed on Saratoga kbd... */
  1236.  
  1237. fkeytest(keycode)
  1238. unsigned char keycode;
  1239. {
  1240.     unsigned char theact = 0;
  1241.     
  1242.     switch (keycode) {
  1243.         case 122: {
  1244.             /* F1 */
  1245.             keyputaction(RSLT_PFKY, PF1);
  1246.             break;
  1247.         }
  1248.         case 120: {
  1249.             /* F2 */
  1250.             keyputaction(RSLT_PFKY, PF2);
  1251.             break;
  1252.         }
  1253.         case 99: {
  1254.             /* F3 */
  1255.             keyputaction(RSLT_PFKY, PF3);
  1256.             break;
  1257.         }
  1258.         case 118: {
  1259.             /* F4 */
  1260.             keyputaction(RSLT_PFKY, PF4);
  1261.             break;
  1262.         }
  1263.         case 96: {
  1264.             /* F5 */
  1265.             keyputaction(RSLT_PFKY, PF5);
  1266.             break;
  1267.         }
  1268.         case 97: {
  1269.             /* F6 */
  1270.             keyputaction(RSLT_PFKY, PF6);
  1271.             break;
  1272.         }
  1273.         case 98: {
  1274.             /* F7 */
  1275.             keyputaction(RSLT_PFKY, PF7);
  1276.             break;
  1277.         }
  1278.         case 100: {
  1279.             /* F8 */
  1280.             keyputaction(RSLT_PFKY, PF8);
  1281.             break;
  1282.         }
  1283.         case 101: {
  1284.             /* F9 */
  1285.             keyputaction(RSLT_PFKY, PF9);
  1286.             break;
  1287.         }
  1288.         case 109: {
  1289.             /* F10 */
  1290.             keyputaction(RSLT_PFKY, PF10);
  1291.             break;
  1292.         }
  1293.         case 103: {
  1294.             /* F11 */
  1295.             keyputaction(RSLT_PFKY, PF11);
  1296.             break;
  1297.         }
  1298.         case 111: {
  1299.             /* F12 */
  1300.             keyputaction(RSLT_PFKY, PF12);
  1301.             break;
  1302.         }
  1303.         case 105: {
  1304.             /* F13 */
  1305.             keyputaction(RSLT_PFKY, PF13);
  1306.             break;
  1307.         }
  1308.         case 107: {
  1309.             /* F14 */
  1310.             keyputaction(RSLT_PFKY, PF14);
  1311.             break;
  1312.         }
  1313.         case 113: {
  1314.             /* F15 */
  1315.             keyputaction(RSLT_PFKY, PF15);
  1316.             break;
  1317.         }
  1318.         default:
  1319.             return(FALSE);
  1320.     }
  1321.     return(TRUE);
  1322. }
  1323.  
  1324.  
  1325. /* ibm mac+ or > keyboard original configuration */
  1326.  
  1327. ibmnkpnorm(thechar, keycode)
  1328. unsigned char thechar;
  1329. unsigned char keycode;
  1330. {
  1331.     /* Mac + NORMKEYPAD */
  1332.     switch (keycode) {
  1333.         case 71: {
  1334.             /* Clear == Clear */
  1335.             keyputaction(RSLT_PFKY, CLEAR);
  1336.             break;
  1337.         }
  1338.         case 123:
  1339.         case 69:
  1340.         case 70: {
  1341.             /* '+' key == + */
  1342.             if (thechar == CTLBACKSLASH)
  1343.                 /* left arrow key on mac+ */
  1344.                 keyputaction(RSLT_MVCR, LEFT_ARROW);
  1345.             else
  1346.                 keyputaction(RSLT_ASCI, '+');
  1347.             break;
  1348.         }
  1349.         case 76: {
  1350.             /* make ENTER == Enter */
  1351.             keyputaction(RSLT_PFKY, ENTER);
  1352.             break;
  1353.         }
  1354.         case 124:
  1355.         case 67:
  1356.         case 66: {
  1357.             /* * == * */
  1358.             if (thechar == CTLRBRACK)
  1359.                 /* right arrow key on mac+ */
  1360.                 keyputaction(RSLT_MVCR, RIGHT_ARROW);
  1361.             else
  1362.                 keyputaction(RSLT_ASCI, '*');
  1363.             break;
  1364.         }
  1365.         case 126:
  1366.         case 75:
  1367.         case 77: {
  1368.             /* / == / */
  1369.             if (thechar == CTLHAT)
  1370.                 /* up arrow key on mac+ */
  1371.                 keyputaction(RSLT_MVCR, UP_ARROW);
  1372.             else
  1373.                 keyputaction(RSLT_ASCI, '/');
  1374.             break;
  1375.         }
  1376.         case 125:
  1377.         case 81:
  1378.         case 72: {
  1379.             /* '=' key == PF2 */
  1380.             if (thechar == CTLUNDERSCORE)
  1381.                 /* down arrow key on mac+ */
  1382.                 keyputaction(RSLT_MVCR, DOWN_ARROW);
  1383.             else
  1384.                 keyputaction(RSLT_ASCI, '=');
  1385.             break;
  1386.         }
  1387.         default: {
  1388.             return(FALSE);
  1389.         }
  1390.     }
  1391.     return(TRUE);
  1392. }
  1393.  
  1394. /* for historical reasons this code handles both keypads 1 & 2 */
  1395.  
  1396. ibmnkp2(thechar, keycode, modifiers)
  1397. unsigned char thechar;
  1398. unsigned char keycode;
  1399. unsigned short modifiers;
  1400. {
  1401.     unsigned char theact = 0;
  1402.     
  1403.     switch (keycode) {
  1404.         /* try keypads KEYPAD1 & KEYPAD2 */
  1405.         /* handle the keys on the keypad, which produce PF, PA, INS, CLR, & ENTER */
  1406.         case 82: {
  1407.             /* '0', next keypad PF key is PF13-24 or PA2 & cousins */
  1408.             if (keydp->keypad == KEYPAD2) {
  1409.                 if (modifiers & shiftKey) 
  1410.                     keyputaction(RSLT_PFKY, PA1);
  1411.                 else if (modifiers & cmdKey) 
  1412.                     keyputaction(RSLT_PFKY, PA3);
  1413.                 else if (modifiers & optionKey) 
  1414.                     keyputaction(RSLT_PFKY, CLEAR);
  1415.                 else
  1416.                     keyputaction(RSLT_PFKY, PA2);
  1417.             }
  1418.             else
  1419.                 keyputaction(RSLT_PFKY, PFSHIFT);
  1420.             break;
  1421.         }
  1422.         case 78: {
  1423.             /* - == PA2 or PA1 */
  1424.             if (keydp->keypad == KEYPAD2)
  1425.                 keyputaction(RSLT_PFKY, PA1);
  1426.             else {
  1427.                 if (modifiers & cmdKey)
  1428.                     keyputaction(RSLT_PFKY, PA3);
  1429.                 else
  1430.                     keyputaction(RSLT_PFKY, PA2);
  1431.             }
  1432.             break;
  1433.         }
  1434.         case 124:
  1435.         case 67:
  1436.         case 66: {
  1437.             /* * == PA1 */
  1438.             if (thechar == CTLRBRACK)
  1439.                 /* right arrow key on mac+ */
  1440.                 keyputaction(RSLT_MVCR, RIGHT_ARROW);
  1441.             else if (keydp->keypad == KEYPAD2)
  1442.                 keyputaction(RSLT_PFKY, PFSHIFT);
  1443.             else
  1444.                 keyputaction(RSLT_PFKY, PA1);
  1445.             break;
  1446.         }
  1447.         case 123:
  1448.         case 69:
  1449.         case 70: {
  1450.             /* + == Clear */
  1451.             if (thechar == CTLBACKSLASH)
  1452.                 /* left arrow key on mac+ */
  1453.                 keyputaction(RSLT_MVCR, LEFT_ARROW);
  1454.             else
  1455.                 keyputaction(RSLT_PFKY, CLEAR);
  1456.             break;
  1457.         }
  1458.         case 76: {
  1459.             /* ENTER == Enter */
  1460.             keyputaction(RSLT_PFKY, ENTER);
  1461.             break;
  1462.         }
  1463.         case 65: {
  1464.             /* . == Insert */
  1465.             keyputaction(RSLT_LCAC, INSRT);
  1466.             break;
  1467.         }
  1468.         /* following this point are the 12 PF keys */
  1469.         case 71: {
  1470.             /* Clear == PF1 */
  1471.             keyputaction(RSLT_PFKY, PF1);
  1472.             break;
  1473.         }
  1474.         case 125:
  1475.         case 81:
  1476.         case 72: {
  1477.             /* '=' key == PF2 */
  1478.             if (thechar == CTLUNDERSCORE)
  1479.                 /* down arrow key on mac+ */
  1480.                 keyputaction(RSLT_MVCR, DOWN_ARROW);
  1481.             else
  1482.                 keyputaction(RSLT_PFKY, PF2);
  1483.             break;
  1484.         }
  1485.         case 126:
  1486.         case 75:
  1487.         case 77: {
  1488.             /* '/' key == PF3 */
  1489.             if (thechar == CTLHAT)
  1490.                 /* up arrow key on mac+ */
  1491.                 keyputaction(RSLT_MVCR, UP_ARROW);
  1492.             else
  1493.                 keyputaction(RSLT_PFKY, PF3);
  1494.             break;
  1495.         }
  1496.         case 89: {
  1497.             /* 7 = PF4 */
  1498.             keyputaction(RSLT_PFKY, PF4);
  1499.             break;
  1500.         }
  1501.         case 91: {
  1502.             /* 8 = PF5 */
  1503.             keyputaction(RSLT_PFKY, PF5);
  1504.             break;
  1505.         }
  1506.         case 92:  {
  1507.             /* 9 = PF6 */
  1508.             keyputaction(RSLT_PFKY, PF6);
  1509.             break;
  1510.         }
  1511.         case 86: {
  1512.             /* 4 = PF7 */
  1513.             keyputaction(RSLT_PFKY, PF7);
  1514.             break;
  1515.         }
  1516.         case 87: {
  1517.             /* 5 = PF8 */
  1518.             keyputaction(RSLT_PFKY, PF8);
  1519.             break;
  1520.         }
  1521.         case 88: {
  1522.             /* 6 = PF9 */
  1523.             keyputaction(RSLT_PFKY, PF9);
  1524.             break;
  1525.         }
  1526.         case 83: {
  1527.             /* 1 = PF10 */
  1528.             keyputaction(RSLT_PFKY, PF10);
  1529.             break;
  1530.         }
  1531.         case 84: {
  1532.             /* 2 = PF11 */
  1533.             keyputaction(RSLT_PFKY, PF11);
  1534.             break;
  1535.         }
  1536.         case 85: {
  1537.             /* 3 = PF12 */
  1538.             keyputaction(RSLT_PFKY, PF12);
  1539.             break;
  1540.         }
  1541.         default: {
  1542.             /* no keypad keys depressed, fall through */
  1543.             return(FALSE);
  1544.         }
  1545.     }
  1546.     if (theact)
  1547.         keyputaction(RSLT_PFKY, theact);
  1548.     return(TRUE);
  1549. }
  1550.  
  1551.  
  1552.  
  1553. ibmnkp3(thechar, keycode)
  1554. unsigned char thechar;
  1555. unsigned char keycode;
  1556. {
  1557.     unsigned char theact = 0;
  1558.     
  1559.     /* do the new Lynn keypad PFs calculator style, else like PAD2 */
  1560.     switch (keycode) {
  1561.         /* handle the keys on the keypad, which produce PF, PA, INS, CLR, & ENTER */
  1562.         case 82: {
  1563.             /* '0', shift */
  1564.             keyputaction(RSLT_PFKY, PFSHIFT);
  1565.             break;
  1566.         }
  1567.         case 78: {
  1568.             /* - == PA2 or PA1 */
  1569.             keyputaction(RSLT_PFKY, PA2);
  1570.             break;
  1571.         }
  1572.         case 124:
  1573.         case 67:
  1574.         case 66: {
  1575.             /* * == PA1 */
  1576.             if (thechar == CTLRBRACK)
  1577.                 /* right arrow key on mac+ */
  1578.                 keyputaction(RSLT_MVCR, RIGHT_ARROW);
  1579.             else
  1580.                 keyputaction(RSLT_PFKY, PA1);
  1581.             break;
  1582.         }
  1583.         case 123:
  1584.         case 69:
  1585.         case 70: {
  1586.             /* + == Clear */
  1587.             if (thechar == CTLBACKSLASH)
  1588.                 /* left arrow key on mac+ */
  1589.                 keyputaction(RSLT_MVCR, LEFT_ARROW);
  1590.             else
  1591.                 keyputaction(RSLT_PFKY, CLEAR);
  1592.             break;
  1593.         }
  1594.         case 76: {
  1595.             /* ENTER == Enter */
  1596.             keyputaction(RSLT_PFKY, ENTER);
  1597.             break;
  1598.         }
  1599.         case 65: {
  1600.             /* . == Insert */
  1601.             keyputaction(RSLT_LCAC, INSRT);
  1602.             break;
  1603.         }
  1604.         /* following this point are the 12 PF keys */
  1605.         case 83: {
  1606.             /* 1 = PF1 */
  1607.             keyputaction(RSLT_PFKY, PF1);
  1608.             break;
  1609.         }
  1610.         case 84: {
  1611.             /* 2 = PF2 */
  1612.             keyputaction(RSLT_PFKY, PF2);
  1613.             break;
  1614.         }
  1615.         case 85: {
  1616.             /* 3 = PF3 */
  1617.             keyputaction(RSLT_PFKY, PF3);
  1618.             break;
  1619.         }
  1620.         case 86: {
  1621.             /* 4 = PF4 */
  1622.             keyputaction(RSLT_PFKY, PF4);
  1623.             break;
  1624.         }
  1625.         case 87: {
  1626.             /* 5 = PF5 */
  1627.             keyputaction(RSLT_PFKY, PF5);
  1628.             break;
  1629.         }
  1630.         case 88: {
  1631.             /* 6 = PF6 */
  1632.             keyputaction(RSLT_PFKY, PF6);
  1633.             break;
  1634.         }
  1635.         case 89: {
  1636.             /* 7 = PF7 */
  1637.             keyputaction(RSLT_PFKY, PF7);
  1638.             break;
  1639.         }
  1640.         case 91: {
  1641.             /* 8 = PF8 */
  1642.             keyputaction(RSLT_PFKY, PF8);
  1643.             break;
  1644.         }
  1645.         case 92:  {
  1646.             /* 9 = PF9 */
  1647.             keyputaction(RSLT_PFKY, PF9);
  1648.             break;
  1649.         }
  1650.         case 71: {
  1651.             /* Clear == PF10 */
  1652.             keyputaction(RSLT_PFKY, PF10);
  1653.             break;
  1654.         }
  1655.         case 125:
  1656.         case 81:
  1657.         case 72: {
  1658.             /* '=' key == PF11 */
  1659.             if (thechar == CTLUNDERSCORE)
  1660.                 /* down arrow key on mac+ */
  1661.                 keyputaction(RSLT_MVCR, DOWN_ARROW);
  1662.             else
  1663.                 keyputaction(RSLT_PFKY, PF11);
  1664.             break;
  1665.         }
  1666.         case 126:
  1667.         case 75:
  1668.         case 77: {
  1669.             /* '/' key == PF12 */
  1670.             if (thechar == CTLHAT)
  1671.                 /* up arrow key on mac+ */
  1672.                 keyputaction(RSLT_MVCR, UP_ARROW);
  1673.             else
  1674.                 keyputaction(RSLT_PFKY, PF12);
  1675.             break;
  1676.         }
  1677.         default:
  1678.             /* no keypad keys depressed, fall through */
  1679.             return(FALSE);
  1680.     }
  1681.     return(TRUE);
  1682. }
  1683.  
  1684.  
  1685.  
  1686. /* handle ibmmode keys producing ibm 7171 key sequences--pf keys 
  1687.     on the main keyboard w/ keypad like arrangement from
  1688.     7-9 & m-. */
  1689.  
  1690. ibmtestpf(keycode, modifiers)
  1691. unsigned char keycode;
  1692. unsigned short modifiers;
  1693. {
  1694.     unsigned char theact;
  1695.     
  1696.     switch (keycode) {
  1697.         case 26: {
  1698.             /* '7' */
  1699.             theact = PF1;
  1700.             break;
  1701.         }
  1702.         case 28: {
  1703.             /* '8' */
  1704.             theact = PF2;
  1705.             break;
  1706.         }
  1707.         case 25: {
  1708.             /* '9' */
  1709.             theact = PF3;
  1710.             break;
  1711.         }
  1712.         case 32: {
  1713.             /* 'u' */
  1714.             theact = PF4;
  1715.             break;
  1716.         }
  1717.         case 34: {
  1718.             /* 'i' */
  1719.             theact = PF5;
  1720.             break;
  1721.         }
  1722.         case 31: {
  1723.             /* 'o' */
  1724.             theact = PF6;
  1725.             break;
  1726.         }
  1727.         case 38: {
  1728.             /* 'j' */
  1729.             theact = PF7;
  1730.             break;
  1731.         }
  1732.         case 40: {
  1733.             /* 'k' */
  1734.             theact = PF8;
  1735.             break;
  1736.         }
  1737.         case 37: {
  1738.             /* 'l' */
  1739.             theact = PF9;
  1740.             break;
  1741.         }
  1742.         case 46: {
  1743.             /* 'm' */
  1744.             theact = PF10;
  1745.             break;
  1746.         }
  1747.         case 43: {
  1748.             /* ',' */
  1749.             theact = PF11;
  1750.             break;
  1751.         }
  1752.         case 47: {
  1753.             /* '.' */
  1754.             theact = PF12;
  1755.             break;
  1756.         }
  1757.         default:
  1758.             return(FALSE);
  1759.             break;
  1760.     }
  1761.     if ( (modifiers & shiftKey) ) {
  1762.         keyputaction(RSLT_PFKY, PFSHIFT);
  1763.     }
  1764.     keyputaction(RSLT_PFKY, theact);
  1765.     return(TRUE);
  1766. }
  1767.  
  1768.  
  1769.  
  1770. /* action queue routines */
  1771.  
  1772. /* add an action to the queue in the keydp context */
  1773.  
  1774. void 
  1775. keyputaction(itemclass, item)
  1776. unsigned char itemclass, item;
  1777. {
  1778.     if (keydp->q_cnt >= MAX_Q) {
  1779.         beep();
  1780.         return;
  1781.     }
  1782.  
  1783.     keydp->q_cnt++;
  1784.     keydp->actqueue[keydp->q_head].class = itemclass;
  1785.     keydp->actqueue[keydp->q_head++].entry = item;
  1786.     if (keydp->q_head >= MAX_Q)
  1787.         keydp->q_head = 0;
  1788. }
  1789.  
  1790.  
  1791. /* add an action to the queue in the emdp context */
  1792.  
  1793. void 
  1794. putaction(itemclass, item)
  1795. unsigned char itemclass, item;
  1796. {
  1797.     if (emdp->q_cnt >= MAX_Q) {
  1798.         beep();
  1799.         return;
  1800.     }
  1801.  
  1802.     emdp->q_cnt++;
  1803.     emdp->actqueue[emdp->q_head].class = itemclass;
  1804.     emdp->actqueue[emdp->q_head++].entry = item;
  1805.     if (emdp->q_head >= MAX_Q)
  1806.         emdp->q_head = 0;
  1807. }
  1808.  
  1809. /* return a pointer to the next action struct */
  1810. /* the following use emdp since they are called during token interpretation
  1811.     for the emulator */
  1812.  
  1813. struct token *
  1814. getaction()
  1815. {
  1816.     struct token * tokep;
  1817.  
  1818.     if (emdp->tokenhold)
  1819.         ++emdp->tokencount;
  1820.     else
  1821.         --emdp->q_cnt;
  1822.     
  1823.     tokep = &emdp->actqueue[emdp->q_tail];
  1824.     if (++emdp->q_tail >= MAX_Q)
  1825.         emdp->q_tail = 0;
  1826.     return( (struct token *) tokep);
  1827. }
  1828.  
  1829.  
  1830. /* return a pointer to the next action struct */
  1831.  
  1832. ungetaction(tokep)
  1833. struct token * tokep;
  1834. {
  1835.     if (emdp->q_cnt >= MAX_Q)
  1836.         return(-1);
  1837.  
  1838.     if (emdp->tokenhold)
  1839.         --emdp->tokencount;
  1840.     else
  1841.         ++emdp->q_cnt;
  1842.     if (--emdp->q_tail < 0)
  1843.         emdp->q_tail = MAX_Q - 1;
  1844.     emdp->actqueue[emdp->q_tail].class = tokep->class;
  1845.     emdp->actqueue[emdp->q_tail].entry = tokep->entry;
  1846. }
  1847.  
  1848.  
  1849. /* save tokens we return from the q for later looping */
  1850.  
  1851. tokenloop(count)
  1852. int count;
  1853. {
  1854.  
  1855.     if (emdp->tokenhold) {
  1856.         /* loop already active */
  1857.         if (count == 0) {
  1858.             /* 0 count terminates a loop */
  1859.             looprewind();
  1860.             return(0);
  1861.         }
  1862.         else {
  1863.             /* TODO not sure this works correctly... cancel the current loop */
  1864.             emdp->q_cnt -= emdp->tokencount;        /* release tokens */
  1865.         }
  1866.     }
  1867.     emdp->tokenhold = TRUE;
  1868.     emdp->loopcount = count;
  1869.     emdp->tokencount = 0;
  1870.     return(0);
  1871. }
  1872.  
  1873. /* loop back to the token just after the first loop argumnet 
  1874.     encountered and decrement the loop counter; if counter goes to zero,
  1875.     terminate loop */ 
  1876.     
  1877. looprewind()
  1878. {
  1879.     if (!emdp->tokenhold)
  1880.         return(-1);
  1881.         
  1882.     if ((emdp->loopcount == -1) || emdp->loopcount) {
  1883.         /* loop again */
  1884.         
  1885.         if (emdp->loopcount != -1)
  1886.             /* decrement if not eternal loop */
  1887.             --emdp->loopcount;
  1888.             
  1889.         emdp->q_tail -= emdp->tokencount;
  1890.         if (emdp->q_tail < 0)
  1891.             emdp->q_tail += MAX_Q;
  1892.     }
  1893.     else {
  1894.         /* done with loop */
  1895.         emdp->q_cnt -= emdp->tokencount;        /* release tokens */
  1896.         emdp->tokenhold = FALSE;
  1897.     }
  1898.     emdp->tokencount = 0;
  1899. }
  1900.  
  1901.  
  1902. matchtoken(thechar)
  1903. unsigned char thechar;
  1904. {
  1905.     struct token * tkptr;
  1906.     
  1907.     if (emdp->tokencount < emdp->q_cnt) {
  1908.         tkptr = getaction();
  1909.         if (tkptr->class == RSLT_ASCI) {
  1910.             if (tkptr->entry != thechar) {
  1911.                 looprewind();
  1912.                 return(FALSE);
  1913.             }
  1914.             else {
  1915.                 /* find out whether next entry is end of match */
  1916.                 if (emdp->tokencount < emdp->q_cnt) {
  1917.                     tkptr = getaction();
  1918.                     ungetaction(tkptr);
  1919.                     if (tkptr->class == RSLT_ASCI) {
  1920.                         /* failure ! */
  1921.                         return(FALSE);
  1922.                     }
  1923.                 }
  1924.                 /* else fall through, we have succeeded */
  1925.             }
  1926.         }
  1927.     }
  1928.     /* success on end of available tokens */
  1929.     emdp->q_cnt -= emdp->tokencount;        /* release tokens */
  1930.     emdp->tokenhold = FALSE;
  1931.     emdp->matchinput = FALSE;
  1932.     return(TRUE);
  1933. }
  1934.  
  1935.  
  1936. flushtokenmatch()
  1937. {
  1938.     struct token * tkptr;
  1939.     
  1940.     looprewind();
  1941.     emdp->tokenhold = FALSE;
  1942.     while (emdp->q_cnt) {
  1943.         /* dump the match string */
  1944.         if (emdp->tokencount < emdp->q_cnt) {
  1945.             tkptr = getaction();
  1946.             if (tkptr->class == RSLT_ASCI)
  1947.                 continue;
  1948.             ungetaction(tkptr);
  1949.             break;
  1950.         }
  1951.     }
  1952.     emdp->matchinput = FALSE;
  1953. }
  1954.  
  1955.  
  1956.  
  1957. /* dump all actions in the queue */
  1958.  
  1959. flushactions(twp)
  1960. struct winds * twp;
  1961. {
  1962.     twp->q_head = 0;
  1963.     twp->q_tail = 0;
  1964.     twp->q_cnt = 0;
  1965.     twp->tokenhold = FALSE;
  1966.     twp->matchinput = FALSE;
  1967.     twp->emdisable = FALSE;
  1968.     twp->loopcount = 0;
  1969.     twp->tokencount = 0;
  1970.     resumetokens(twp);            /* abort any DELAY tokens */
  1971.     if (twp->emwindow && twp->macroexecuting) {
  1972.         /* reset the macro flag */
  1973.         twp->macroexecuting = FALSE;
  1974.         InvalRect(&twp->macrorect);
  1975.         
  1976.         /* and reset the button bar */
  1977.         reset25(twp);
  1978.     }
  1979. }
  1980.  
  1981.  
  1982. /* the following assembly language routines interface to the old System 4.1
  1983.     key mapping interface, now superseded by the Script Mgr */
  1984.     
  1985. long * keytrans;    /* actually void * (*keytrans)() ? but who cares ? */
  1986. long * key1tran;    /* the original system key handling routine */
  1987.  
  1988. #asm
  1989. ; this routine resets the option key flag so NO option key remapping is done by 
  1990. ; the standard macintosh key configuration code; the option-key-down bit is 
  1991. ; cleared
  1992.  
  1993.     public keyend_
  1994.  
  1995. OrigA5 EQU $904
  1996.  
  1997. cseg
  1998.  
  1999.     public keytrap_
  2000. keytrap_:
  2001.     move.l  a5,a3
  2002.     move.l    (OrigA5),A5
  2003.             ; end of save routine
  2004.     bclr    #2,d1    ; clear option key bit
  2005. norm_:
  2006.     move.l    _key1tran,a2
  2007.     jsr        (a2)
  2008. keyend_:
  2009.     move.l    a3,a5
  2010.     rts
  2011.  
  2012. #endasm
  2013.  
  2014.  
  2015. keyclose()
  2016. {
  2017.     if (GetTrapAddress(0x9f) != GetTrapAddress(0xb5) ) {
  2018.         setscript(0L);        /* restore standard system script on exit() */
  2019.     }
  2020.     else {
  2021.         if (!keytron)
  2022.             return(0);
  2023.     
  2024.         keytron = FALSE;
  2025. #asm
  2026.     move.l    _keytrans,a2
  2027.     move.l    _key1tran,(a2)
  2028. #endasm
  2029.     }
  2030. }
  2031.  
  2032.  
  2033. /* patch in a key resource desc with the Script Mgr which will pass
  2034.     the option keys */
  2035.     
  2036. keyinit()
  2037. {
  2038.     long script;
  2039.  
  2040.     if (GetTrapAddress(0x9f) != GetTrapAddress(0xb5) ) {
  2041.         /* if script manager is not == Unimplemented, use it */
  2042.         setscript((long) EINUSCRIPT);            
  2043.     }
  2044.     else {
  2045.         /* add our old System key filter to preprocess keys before the standard one */
  2046.         if (keytron)
  2047.             return(0);
  2048.     
  2049.         keytron = TRUE;
  2050.  
  2051.         keytrans = 0x29e;
  2052.         key1tran = (long *) *keytrans;
  2053.  
  2054.         /* *keytrans = (long *) keytrap; */
  2055. #asm
  2056.         move.l    _keytrans,a2
  2057.         lea        keytrap_,a1
  2058.         move.l    a1,(a2)
  2059. #endasm
  2060.     }
  2061.     exit_hook(keyclose);
  2062. }
  2063.  
  2064.  
  2065.  
  2066.  
  2067.